using System;
using System.Collections.Generic;
using System.Text;

using System.Runtime.InteropServices;
using ZoneFiveSoftware.Common.Data;
using ZoneFiveSoftware.Common.Data.Fitness;

using ZoneFiveSoftware.Common.Visuals;
using ZoneFiveSoftware.Common.Visuals.Fitness;

namespace PolarImport.DeviceImporter
{
    class PolarF6 : IFitnessDevice 
    {
        /// <summary>
        /// Constructor of the FitnessDevice. Set GUID, image, name and connection information.
        /// </summary>
        public PolarF6()
        {
            this.id = new Guid("1b3ace2e-c675-475f-b83c-b20d04117079");
            this.image = Properties.Resources.Img_Polar_HRM_F6;
            this.name = "Polar F6";
            this.connection = "SonicLink";
        } 
        #region IFitnessDevice Member

        /// <summary>
        /// Something about Properties of the connection... 
        /// </summary>
        /// <param name="configurationInfo">???</param>
        /// <returns>Properties?</returns>
        public string Configure(string configurationInfo)
        {
            return "";
        }

        /// <summary>
        /// The name and the connection method of this POLAR HRM.
        /// </summary>
        /// <param name="configurationInfo">???</param>
        /// <returns>The name and the connection method of this POLAR HRM.</returns>
        public string ConfiguredDescription(string configurationInfo)
        {
            return name + Environment.NewLine + connection;
        }

        #endregion

        #region IDataImporter Member

        /// <summary>
        /// The name of this POALR HRM.
        /// </summary>
        public string Name
        {
            get { return name; }
        }

        /// <summary>
        /// The unique ID of this FitnessDevice.
        /// </summary>
        public Guid Id
        {
            get { return id; }
        } 

        /// <summary>
        /// The image to represent this POLAR HRM in import dialog of SportTracks.
        /// </summary>
        public System.Drawing.Image Image
        {
            get { return image; }
        }

        /// <summary>
        /// The implementation of the import algorithm. Start communication with the POLAR HRM and read the
        /// raw data. The processing of this data is done by the function <see cref="PolarF6.ProcessData"/>.
        /// </summary>
        /// <param name="configurationInfo">Configuration info of the POLAR HRM</param>
        /// <param name="monitor">The active job monitor for this import. Shows progress of import.</param>
        /// <param name="importResults">The imported data. This data is processed by SportTrack safter successful import.</param>
        /// <returns>True, if import was successful.<br></br>False, if import fails.</returns>
        public bool Import(string configurationInfo, IJobMonitor monitor, IImportResults importResults)
        {
            int version = PolarHRM.GetLibraryVersion();
            PolarImportForm ImportWindow = new PolarImportForm();
            ImportWindow.Text = name;
            ImportWindow.Show();
            if (MessageDialog.Show(string.Format(Properties.Resources.PolarImport_General_PlaceHRMSonicLink, name),
                name, System.Windows.Forms.MessageBoxButtons.OKCancel, System.Windows.Forms.MessageBoxIcon.Information ) ==
                System.Windows.Forms.DialogResult.Cancel)
            {
                return false;  // Abort by user
            }
            monitor.StatusText = Properties.Resources.PolarImport_General_ReadingData;
            monitor.PercentComplete = 0.0f;
            int readdata = PolarHRM.ReadSonicLinkData(ImportWindow.Handle, (int) MonitorType.HRM_F6, 0, 2, false);
            switch (readdata)
            {
                case 0: // Cancelled
                    {
                        monitor.StatusText = Properties.Resources.PolarImport_General_ReadingCancelled;
                        monitor.ErrorText = Properties.Resources.PolarImport_General_ReadingCancelled;
                        ImportWindow.Dispose();
                        return false;
                    }
                case 1: // Successfull
                    {
                        monitor.StatusText = Properties.Resources.PolarImport_General_ReadingSucces;
                        ImportWindow.Dispose();
                        return ProcessData(monitor, importResults);
                    }
                case 2: // Retry
                    {
                        monitor.StatusText = Properties.Resources.PolarImport_General_Retry;
                        // Call the import function recursive!
                        ImportWindow.Dispose();
                        return Import(configurationInfo, monitor, importResults);
                    }
            }
            monitor.ErrorText = Properties.Resources.PolarImport_General_Not_implemented;
            ImportWindow.Dispose();
            return false;
            
        }

        /// <summary>
        /// Processing of the raw data read by Import function. Store processed data in corresponding
        /// SportTracks structures
        /// </summary>
        /// <param name="monitor">The active job monitor for this import. Shows progress of import.</param>
        /// <param name="importResults">The imported data. This data is processed by SportTrack safter successful import.</param>
        /// <returns>True, if data processing was successful.<br></br>False, if data processing fails.</returns>
        private bool ProcessData(IJobMonitor monitor, IImportResults importResults)
        {
            int FitnessFileCount = PolarHRM.GetFitnessFileCount();
            if (FitnessFileCount > 0)
            {
                for (int FitnessFile = 0; FitnessFile < FitnessFileCount; FitnessFile++)
                {
                    monitor.StatusText = string.Format(Properties.Resources.PolarImport_Import_FitnessFileCount +
                        Environment.NewLine, FitnessFileCount) +
                        string.Format(Properties.Resources.PolarImport_Import_ProcessingFile, FitnessFile);
                    monitor.PercentComplete = (float)FitnessFile / (float)FitnessFileCount;

                    PolarHRM.AnalyzeFile(FitnessFile, 0);

                    DateTime startdate = PolarHRM.ConvertHRMDate(PolarHRM.GetRecParam(RecData.REC_START_DATE));
                    DateTime starttime = PolarHRM.ConvertHRMTime(PolarHRM.GetRecParam(RecData.REC_START_TIME));
                    DateTime startDateTime = new DateTime(startdate.Year, startdate.Month, startdate.Day, starttime.Hour, starttime.Minute, starttime.Second);
                    // Maybe it is not necessary to convert to UniversalTime. For me it works. The StartTime is correct. Without
                    // this the StartTime is 1 hour to much.
                    startDateTime = startDateTime.ToUniversalTime();
                    IActivity activity = importResults.AddActivity(startDateTime);

                    activity.AverageHeartRatePerMinuteEntered = PolarHRM.GetRecParam(RecData.REC_AVE_HRATE);
                    activity.MaximumHeartRatePerMinuteEntered = PolarHRM.GetRecParam(RecData.REC_MAX_HRATE);
                    activity.TotalTimeEntered = new TimeSpan(0, 0, PolarHRM.GetRecParam(RecData.REC_REC_LENGTH) / 1000);
                    activity.TotalCalories = PolarHRM.GetRecParam(RecData.REC_CALORIES);
                    activity.MaximumHeartRatePerMinuteEntered = PolarHRM.GetRecParam(RecData.REC_MAX_HRATE);
                    activity.Notes += Properties.Resources.PolarImport_Import_DirectImportFrom + " " + name + Environment.NewLine;
                    activity.Notes += String.Format(Properties.Resources.PolarImport_F6_Fatconsumption + Environment.NewLine, PolarHRM.GetRecParam(RecData.REC_FATCONSUMPTION));
                    activity.UseEnteredData = true;
                    activity.HasStartTime = true;

                    // enter all data in the notes field.
                    // For test versions uncomment the following:
                    //foreach (RecData recdata in Enum.GetValues(typeof(RecData)))
                    //{
                    //    activity.Notes += recdata.ToString() + " = " + PolarHRM.GetRecParam(recdata).ToString() +Environment.NewLine;
                    //}
                    
                }
                return true;
            }
            monitor.ErrorText = Properties.Resources.PolarImport_Import_NoFitnessFileFound ;
            return false;
        }


        #endregion

        #region Private members

        /// <summary>The unique GUID of this FitnessDevice</summary>
        private Guid id;

        /// <summary>The image to represent this FitnessDevice</summary>
        private System.Drawing.Image image;

        /// <summary>The name of this FitnessDevice</summary>
        private string name;

        /// <summary>The connectiontype of this FitnessDevice. SonicLink or IR.</summary>
        private string connection;
        
        #endregion

        
    }
}
